package com.example.demo.security.filter;

import cn.hutool.core.util.StrUtil;
import com.example.demo.common.constant.SecurityConstants;
import com.example.demo.common.util.ResponseUtils;
import com.example.demo.model.core.ResultCode;
import com.example.demo.security.service.CaptchaOperation;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpMethod;
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;


/**
 * 图形验证码校验过滤器
 */
public class CaptchaValidationFilter extends OncePerRequestFilter {

    private static final PathPatternRequestMatcher LOGIN_PATH_REQUEST_MATCHER = PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, SecurityConstants.LOGIN_PATH);

    public static final String CAPTCHA_CODE_PARAM_NAME = "captchaCode";
    public static final String CAPTCHA_KEY_PARAM_NAME = "captchaKey";


    private final CaptchaOperation captchaOperation;

    public CaptchaValidationFilter(CaptchaOperation captchaOperation) {
        this.captchaOperation = captchaOperation;
    }

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 检验登录接口的验证码
        if (LOGIN_PATH_REQUEST_MATCHER.matches(request)) {
            // 请求中的验证码
            String captchaCode = request.getParameter(CAPTCHA_CODE_PARAM_NAME);
            // TODO 兼容没有验证码的版本(线上请移除这个判断)
            if (StrUtil.isBlank(captchaCode)) {
                chain.doFilter(request, response);
                return;
            }
            // 缓存中的验证码
            String verifyCodeKey = request.getParameter(CAPTCHA_KEY_PARAM_NAME);

            if (captchaOperation.vilidate(verifyCodeKey, captchaCode)) {
                chain.doFilter(request, response);
            } else {
                ResponseUtils.writeErrMsg(response, ResultCode.USER_VERIFICATION_CODE_ERROR);
            }
        } else {
            // 非登录接口放行
            chain.doFilter(request, response);
        }
    }

}
